#include <intrins.h>
#include <uart.h>
#include <queBase.h>

#if UART_ENABLE_FLAG_1
static char DEV_C51_XDATA_FLAG uartRcvQueue_1[140];
#define UART1_BRT (65535 - STC_WORK_SYSCLK / 115200 / 4)
void uartInit_1()
{
#if DEV_PLAT_51_CHIP_TYPE == DEV_PLAT_51_STC32
    SCON = 0x50; // 8位数据,可变波特率
    T2L = UART1_BRT;
    T2H = UART1_BRT >> 8;
    S1BRT = 1;
    T2x12 = 1;
    T2R = 1;
    ES = 1;
#else
    PCON &= 0x7F; // 波特率不倍速
    SCON = 0x50;  // 8位数据,可变波特率
    AUXR |= 0x04; // 定时器时钟1T模式
    BRT = 0xFD;   // 设置定时重载值
    AUXR |= 0x01; // 串口1使用独立波特率发射器为波特率发生器
    AUXR |= 0x10; // 启动独立波特率发射器
    ES = 1;       // 打开接收中断

    // SCON = 0X50;     // 设置串口1:工作方式1
    // AUXR |= 0x40;    // 定时器时钟1T模式
    // AUXR &= 0xFE;    // 串口1选择定时器1为波特率发生器
    // TMOD &= 0x0F;    // 设置定时器模式
    // TL1 = UART1_BRT; ////65536-24*1024*1024/115200/4
    // TH1 = UART1_BRT >> 8;
    // ET1 = 0; // 禁止定时器中断
    // ES = 1;  // 打开接收中断
    // TR1 = 1; // 运行计数器1
#endif
    queOptInit(uartRcvQueue_1, sizeof(uartRcvQueue_1));
}

void uartIterrupte_1() interrupt 4
{
    uint8_t tmpval;
    if (RI)
    {
        RI = 0; // 清中断标志
        tmpval = SBUF;
        queOptWrite(uartRcvQueue_1, &tmpval, 1);
    }
    // if (TI)
    // {
    //     TI = 0; //清中断标志
    // }
}

void uartSndByte_1(uint8_t byte)
{
    SBUF = byte;
    while (!TI)
        ;
    TI = 0;
}

void uartSndStr_1(uint8_t *str, uint16_t strlen)
{
    uint16_t k = 0;
    for (k = 0; k < strlen; k++)
    {
        uartSndByte_1(*str++);
    }
}

uint16_t uartRcvStr_1(uint8_t *outbuf, uint16_t len)
{
    return queOptRead(uartRcvQueue_1, 0, outbuf, len);
}
#endif

#if UART_ENABLE_FLAG_2
static xdata char uartRcvQueue_2[140];
#define UART2_BRT (65535 - STC_WORK_SYSCLK / 115200 / 4)
void uartInit_2()
{
    S2CON = 0x50;
    T2L = UART2_BRT;
    T2H = UART2_BRT >> 8;
    AUXR |= 0x04; // 定时器时钟1T模式
    AUXR |= 0x10; // 定时器2开始计时
    IE2 |= 0x01;
    // setValBits(AUXR, 4, 1, 1);
    // setValBits(AUXR, 2, 1, 1);
    // setValBits(IE2, 0, 1, 1);
    queOptInit(uartRcvQueue_2, sizeof(uartRcvQueue_2));
}

void uart2Interrupt() interrupt 8
{
    uint8_t tmpval;
    if (S2CON & 0x01)
    {
        S2CON &= ~0x01;
        tmpval = S2BUF;
        queOptWrite(uartRcvQueue_2, &tmpval, 1);
    }
}

void uartSndByte_2(char byte)
{
    S2BUF = byte;
    while (!(S2CON & 0x02))
        ;
    S2CON &= ~0x02;
}

void uartSndStr_2(uint8_t *str, uint16_t strlen)
{
    uint16_t k = 0;
    for (k = 0; k < strlen; k++)
    {
        uartSndByte_2(*str++);
    }
}

uint16_t uartRcvStr_2(uint8_t *str, uint16_t strlen)
{
    return queOptRead(uartRcvQueue_2, 0, str, strlen);
}
#endif

#if UART_ENABLE_FLAG_3
#define UART3_BRT (65535 - STC_WORK_SYSCLK / 9600 / 4)
void uartInit_3()
{
    S3CON = 0x50;
    T3L = UART3_BRT;
    T3H = UART3_BRT >> 8;
    setValBits(T4T3M, 0, 0x0f, 0x0a);
    // T4T3M = 0x0a;
    setValBits(IE2, 3, 1, 1);
}
void uart3Isr() interrupt 17
{
    if (S3CON & 0x01)
    {
        S3CON &= ~0x01;
        // S3BUF
    }
}
void uartSndByte_3(char byte)
{
    S3BUF = byte;
    while (!(S3CON & 0x02))
        ;
    S3CON &= ~0x02;
}
void uartSndStr_3(uint8_t *str, u16 strlen)
{
    u16 k = 0;
    for (k = 0; k < strlen; k++)
    {
        uartSndByte_3(*str++);
    }
}
#endif

#if UART_ENABLE_FLAG_4
struct fifoBuffDefine xdata uart4RecvFifo;
#define UART4_BRT (65535 - STC_WORK_SYSCLK / 57600 / 4)
void uartInit_4()
{
    S4CON = 0x50;
    T4L = UART4_BRT;
    T4H = UART4_BRT >> 8;
    // T4T3M = 0x0a;
    setValBits(P_SW2, 2, 1, 1);
    setValBits(T4T3M, 4, 0x0f, 0x0a);
    setValBits(IE2, 4, 1, 1);
    fifoBufferInit(&uart4RecvFifo);
}
void uart4Isr() interrupt 18
{
    if (S4CON & 0x01)
    {
        S4CON &= ~0x01;
        // S4BUF
        fifoBuffer4InputByte(&uart4RecvFifo, S4BUF);
    }
}
void uartSndByte_4(char byte)
{
    S4BUF = byte;
    while (!(S4CON & 0x02))
        ;
    S4CON &= ~0x02;
}
void uartSndStr_4(uint8_t *str, u16 strlen)
{
    u16 k = 0;
    for (k = 0; k < strlen; k++)
    {
        uartSndByte_4(*str++);
    }
}

uint16_t uartRcvStr_4(uint8_t *outbuf, uint16_t len)
{
    return fifoBufferOutputStr(&uart4RecvFifo, outbuf, len);
}
#endif
